package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.UserDto;
import com.zzyl.entity.Role;
import com.zzyl.entity.User;
import com.zzyl.entity.UserRole;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeptMapper;
import com.zzyl.mapper.RoleMapper;
import com.zzyl.mapper.UserMapper;
import com.zzyl.mapper.UserRoleMapper;
import com.zzyl.service.UserService;
import com.zzyl.utils.EmptyUtil;
import com.zzyl.utils.NoProcessing;
import com.zzyl.vo.RoleVo;
import com.zzyl.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public PageResponse<UserVo> findUserPage(UserDto userDto, int pageNum, int pageSize) {
        // 处理部门编号，进行特定的字符串处理
        if (!EmptyUtil.isNullOrEmpty(userDto.getDeptNo())) {
            userDto.setDeptNo(NoProcessing.processString(userDto.getDeptNo()));
        }
        PageHelper.startPage(pageNum, pageSize);
        Page<User> userPage = userMapper.findUserPage(userDto);

        PageResponse<UserVo> pageResponse = PageResponse.of(userPage, UserVo.class);

        if (!EmptyUtil.isNullOrEmpty(pageResponse.getRecords())) {
            //提取用户id列表，为后续查询用户角色做准备
            List<Long> userIds = pageResponse.getRecords().stream().map(UserVo::getId).collect(Collectors.toList());
            //根据用户id列表查询用户角色
            List<RoleVo> roleVos = roleMapper.findRoleByUserIds(userIds);
            log.info("根据用户id列表查询用户角色:{}", roleVos);
            //遍历用户列表，为每个用户添加角色列表
            pageResponse.getRecords().forEach(n -> {
                //为当前用户装配角色ID集合和名称集合
                Set<String> roleVoIds = new HashSet<>();
                Set<String> roleVoLabels = new HashSet<>();
                roleVos.forEach(m -> {
                    if (String.valueOf(n.getId()).equals(m.getUserId())) {
                        roleVoIds.add(String.valueOf(m.getId()));
                        roleVoLabels.add(m.getRoleName());
                    }
                });
                n.setRoleVoIds(roleVoIds);
                n.setRoleLabels(roleVoLabels);

            });

        }
        return pageResponse;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserVo createUser(UserDto userDto) {

        //根据部门编号查询，是否是最底层的部门，如果不是，不允许添加用户
        if (isLowestDept(userDto.getDeptNo())) {
            throw new BaseException(BasicEnum.USER_LOCATED_BOTTOMED_DEPT);
        }

        //转换UserVo为User
        User user = BeanUtil.toBean(userDto, User.class);
        user.setUsername(user.getEmail());
        user.setNickName(user.getRealName());
        user.setDataState(SuperConstant.DATA_STATE_0);
        //TODO 需要设置默认，并且需要加密
        String password = "itcast";
        user.setPassword(password);

        int flag = userMapper.insertUser(user);
        //观察是否保存成功，返回主键是否等于0
        if (flag == 0) {
            throw new RuntimeException("保存用户信息出错");
        }
        //保存用户角色中间表
        List<UserRole> userRoles = new ArrayList<>();
        userDto.getRoleVoIds().forEach(r -> {
            userRoles.add(UserRole.builder()
                    .userId(user.getId())
                    .roleId(Long.valueOf(r))
                    .dataState(SuperConstant.DATA_STATE_0)
                    .build());
        });
        flag = userRoleMapper.batchInsert(userRoles);
        if (flag == 0) {
            throw new RuntimeException("保存用户角色中间表出错");
        }

        return BeanUtil.toBean(user, UserVo.class);
    }

    @Override
    @Transactional
    public Boolean updateUser(UserDto userDto) {
        //根据部门编号查询，是否是最底层的部门，如果不是，不允许添加用户
        if (isLowestDept(userDto.getDeptNo())) {
            throw new BaseException(BasicEnum.USER_LOCATED_BOTTOMED_DEPT);
        }

        //转换UserVo为User
        User user = BeanUtil.toBean(userDto, User.class);
        user.setUsername(userDto.getEmail());

        int flag = userMapper.updateByPrimaryKeySelective(user);

        if (flag == 0) {
            throw new RuntimeException("修改用户信息出错");
        }


        if (CollUtil.isNotEmpty(userDto.getRoleVoIds())) {
            //删除角色中间表
            boolean flagDel = userRoleMapper.deleteUserRoleByUserId(user.getId());
            if (!flagDel) {
                throw new RuntimeException("删除角色中间表出错");
            }

            //重新保存角色中间表
            List<UserRole> userRoles = new ArrayList<>();

            userDto.getRoleVoIds().forEach(r -> {

                UserRole userRole = UserRole.builder()
                        .userId(user.getId())
                        .roleId(Long.valueOf(r))
                        .dataState(SuperConstant.DATA_STATE_0)
                        .build();

                userRoles.add(userRole);

            });

            flag = userRoleMapper.batchInsert(userRoles);

            if (flag == 0) {
                throw new RuntimeException("保存角色中间表出错");
            }
        }

        return true;
    }

    @Override
    public void deleteUserById(Long userIds) {
// 删除用户与角色关联
        userRoleMapper.deleteUserRoleByUserId(userIds);
        // 删除用户与岗位关联
        userMapper.deleteByPrimaryKey(userIds);

    }

    @Override
    public void isEnableByIdUser(Long id, String status) {
       User user = userMapper.selectByPrimaryKey(id);
       if (user == null){
           throw new BaseException(BasicEnum.USER_EMPTY_EXCEPTION);
       }
       user.setDataState(status);
       userMapper.updateByPrimaryKeySelective(user);

    }

    @Override
    public List<UserVo> findAllUser(UserDto userDto) {
       List<User> users = userMapper.selectByRealName(userDto.getRealName());

        List<UserVo> userVos = BeanUtil.copyToList(users, UserVo.class);
        return userVos;


    }


    private boolean isLowestDept(String deptNo) {
        int count = deptMapper.isLowestDept(deptNo);
        if (count > 0) {
            return true;
        }
        return false;
    }
}
